package com.xyy.saas.payment.util;

import com.unionpay.acp.sdk.SDKConfig;
import com.unionpay.acp.sdk.SDKUtil;
import com.unionpay.acp.sdksample.multicert.DemoBase;
import com.xyy.saas.common.assist.StringUtils;
import com.xyy.saas.payment.cores.vo.UnionPayConfigVo;
import com.xyy.saas.payment.payment.core.dto.PayDto;
import com.xyy.saas.payment.payment.core.dto.RefundDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;

import java.util.*;

/**
 * @program: xyy-ec-order-business-all
 * @description: 银联支付工具类
 * @author: wcwanga
 * @create: 2019-10-25 10:43:10
 **/
@Configuration
public class UnionPayUtils {

    public static final String UNIONPAY_BACK_REFUND_NOTIFY_URL = "unionpay_back_refund_notify_url";
    public static final String UNIONPAY_BACK_PAY_NOTIFY_URL = "unionpay_back_pay_notify_url";
    public static final String UNIONPAY_FRONT_PAY_NOTIFY_URL = "unionpay_front_pay_notify_url";
    private static final Logger logger = LoggerFactory.getLogger(UnionPayUtils.class);

    /** 商户代码 */
    private static String APP_ID;

    private static final String DEFAULT_METHOD = "01";         //签名方法 目前只支持01-RSA方式证书加密
    private static final String DEFAULT_TXNTYPE0 = "01";         //交易类型 01-支付
    private static final String DEFAULT_TXNTYPE1 = "04";         //交易类型 04-退货
    private static final String DEFAULT_TXNSUBTYPE0 = "00";     //交易子类型  默认00 退货
    private static final String DEFAULT_TXNSUBTYPE1 = "01";     //交易子类型  默认01 支付
    private static final String DEFAULT_BIZTYPE = "000201"; //业务类型
    private static final String DEFAULT_ACCESSTYPE = "0";      //接入类型，商户接入固定填0，不需修改
    private static final String DEFAULT_CURRENCYCODE = "156";   //交易币种（境内商户一般是156 人民币）
    private static final int DEFAULT_PAYSTATUES = 90;   //交易币种（境内商户一般是156 人民币）
    private static final int DEFAULT_TSTATUES = 91;   //交易币种（境内商户一般是156 人民币）
    private static final String pot = "＇";
    private static final int DEFAULT_PAYTYPE = 3;   //支付类型

    public Map<String, String> post(String requestUrl, Map<String, String> submitFromData) {
        logger.info("银联调用参数："+submitFromData);
        String resultString = SDKUtil.send(requestUrl, submitFromData, DemoBase.encoding, 40000, 40000);
        logger.info("银联调用返回结果："+resultString);
        if (null != resultString && !"".equals(resultString)) {
            return SDKUtil.convertResultStringToMap(resultString);
        } else {
            return null;
        }
    }

    public String createHtml(String action, Map<String, String> hiddens) {
        StringBuffer sf = new StringBuffer();
        sf.append("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/></head><body>");
        sf.append("<form id = \"pay_form\" action=\"" + action
                + "\" method=\"post\">");
        if (hiddens != null && !hiddens.isEmpty()) {
            Set<Map.Entry<String, String>> set = hiddens.entrySet();
            Iterator<Map.Entry<String, String>> it = set.iterator();
            while (it.hasNext()) {
                Map.Entry<String, String> ey = it.next();
                String key = ey.getKey();
                String value = ey.getValue();
                sf.append("<input type=\"hidden\" name=\"" + key + "\" id=\""
                        + key + "\" value=\"" + value + "\"/>");
            }
        }
        sf.append("</form>");
        sf.append("</body>");
        sf.append("<script type=\"text/javascript\">");
        sf.append("document.all.pay_form.submit();");
        sf.append("</script>");
        sf.append("</html>");
        return sf.toString();
    }

    /**
     * @param contentData 支付参数。
     * @return String 签名后的map对象
     * @throws
     * @方法名称:signData
     * @内容摘要: ＜对数据进行签名＞
     * @author:fangwei
     * @创建日期:2016年4月12日-下午4:53:30
     */
    public Map<String, String> signData(Map<String, ?> contentData) throws Exception{
        Map.Entry<String, String> obj = null;
        Map<String, String> submitFromData = new HashMap<String, String>();
        for (Iterator<?> it = contentData.entrySet().iterator(); it.hasNext(); ) {
            obj = (Map.Entry<String, String>) it.next();
            String value = obj.getValue();
            if (StringUtils.isNotEmpty(value)) {
                submitFromData.put(obj.getKey(), value.trim());
            }
        }
        SDKUtil.sign(submitFromData, DemoBase.encoding);
        return submitFromData;
    }

    public void init(UnionPayConfigVo unionPayConfigVo) {
        SDKConfig.getConfig().loadPropertiesFromSrc();
        APP_ID = unionPayConfigVo.getAppId();
    }


    public SortedMap joinPayRequestData(PayDto payDto){
        SortedMap params = joinCommonRequestData();
        //交易类型 ，01：消费，00：默认
        params.put("txnType", DEFAULT_TXNTYPE0);
        //交易子类型， 01：自助消费，00：默认
        params.put("txnSubType", DEFAULT_TXNSUBTYPE1);
        //业务类型，B2C网关支付，手机wap支付，默认取值：000000
        params.put("bizType", DEFAULT_BIZTYPE);
        //接入类型，0：直连商户，1：收单机构接入，2：平台商户接入
        params.put("accessType", DEFAULT_ACCESSTYPE);
        //交易币种（境内商户一般是156 人民币）
        params.put("currencyCode", DEFAULT_CURRENCYCODE);
        //商户号码，请改成自己申请的正式商户号或者open上注册得来的777测试商户号
        params.put("merId", APP_ID);

        //商户订单号，8-40位数字字母，不能含“-”或“_”，可以自行定制规则
        params.put("orderId", payDto.getPayNo());
        //订单发送时间，取系统时间，格式为YYYYMMDDhhmmss，必须取当前时间，否则会报txnTime无效
        params.put("txnTime", DateUtil.currentTimestamp2String(DateUtil.YYYYMMDDHHMMSS));
        //交易金额，单位分，不要带小数点
        params.put("txnAmt", String.valueOf(payDto.getAmount()));
        params.put("orderDesc", payDto.getBusinessOrderNo());

        return params;
    }

    public SortedMap joinQueryRequestData(String tradeNo, Date payTime) {
        SortedMap params = joinCommonRequestData();
        //交易类型 ，01：消费，00：默认
        params.put("txnType", "00");
        //交易子类型， 01：自助消费，00：默认
        params.put("txnSubType", "00");
        //业务类型，B2C网关支付，手机wap支付，默认取值：000000
        params.put("bizType", "000000");
        //接入类型，0：直连商户，1：收单机构接入，2：平台商户接入
        params.put("accessType", DEFAULT_ACCESSTYPE);
        //商户代码
        params.put("merId", APP_ID);
        // 订单发送时间
        params.put("txnTime", DateUtil.date2String(payTime,DateUtil.YYYYMMDDHHMMSS));
        //商户订单号
        params.put("orderId", tradeNo);

        return params;
    }


    public SortedMap joinRefundRequestData(RefundDto refundDto){
        SortedMap params = joinCommonRequestData();
        //交易类型 ，01：消费，00：默认， 04：退货
        params.put("txnType", DEFAULT_TXNTYPE1);
        //交易子类型， 01：自助消费，00：默认

        params.put("txnSubType", DEFAULT_TXNSUBTYPE0);
        //业务类型，B2C网关支付，手机wap支付，默认取值：000000
        params.put("bizType", DEFAULT_BIZTYPE);

        String url = ApolloUtil.getProperty(UNIONPAY_BACK_REFUND_NOTIFY_URL);
        // 后台通知地址
        params.put("backUrl", url);
        //接入类型，0：直连商户，1：收单机构接入，2：平台商户接入
        params.put("accessType", DEFAULT_ACCESSTYPE);
        //商户订单号
        params.put("merId", APP_ID);
        // 交易币种
        params.put("currencyCode", DEFAULT_CURRENCYCODE);

        return params;
    }

    public SortedMap joinCommonRequestData(){
        SortedMap params = new TreeMap();

        /***银联全渠道系统，产品参数，除了encoding自行选择外其他不需修改***/
        params.put("version", DemoBase.version);
        //字符集编码，可以使用UTF-8,GBK两种方式
        params.put("encoding", DemoBase.encoding);
        //签名方法 目前只支持01-RSA方式证书加密
        params.put("signMethod", DEFAULT_METHOD);

        return params;
    }
}